<template>
  <div role="application"
       aria-label="Sketch color picker"
       :class="['vc-sketch', disableAlpha ? 'vc-sketch__disable-alpha' : '']">
    <div class="vc-sketch-saturation-wrap">
      <saturation :colors="val" @change="childChange"></saturation>
    </div>
    <div class="vc-sketch-controls">
      <div class="vc-sketch-sliders">
        <div class="vc-sketch-hue-wrap">
          <hue :colors="val" @change="childChange"></hue>
        </div>
        <div class="vc-sketch-alpha-wrap" v-if="!disableAlpha">
          <alpha :colors="val" @change="childChange"></alpha>
        </div>
      </div>
      <div class="vc-sketch-color-wrap">
        <div :aria-label="`Current color is ${activeColor}`" class="vc-sketch-active-color"
             :style="{background: activeColor}"></div>
        <check-board></check-board>
      </div>
    </div>
    <div class="vc-sketch-field" v-if="!disableFields">
      <!-- rgba -->
      <div class="vc-sketch-field--double">
        <editable-input label="hex" :value="hex" @change="inputChange"></editable-input>
      </div>
      <div class="vc-sketch-field--single">
        <editable-input label="r" :value="val.rgba.r" @change="inputChange"></editable-input>
      </div>
      <div class="vc-sketch-field--single">
        <editable-input label="g" :value="val.rgba.g" @change="inputChange"></editable-input>
      </div>
      <div class="vc-sketch-field--single">
        <editable-input label="b" :value="val.rgba.b" @change="inputChange"></editable-input>
      </div>
      <div class="vc-sketch-field--single" v-if="!disableAlpha">
        <editable-input label="a" :value="val.a" :arrow-offset="0.01" :max="1" @change="inputChange"></editable-input>
      </div>
    </div>
    <div class="vc-sketch-presets" role="group" aria-label="A color preset, pick one to set as current color">
      <div class="vc-group">
        <el-select class="vc-group-select"
                   :show-arrow="false"
                   :offset="0"
                   v-model="selectedGroup"
                   popper-class="vc-group-select-popper"
                   @change="onPresetsChange"
                   :popper-append-to-body="false"
        >
          <el-option v-for="item in groups"
                     :key="item.value"
                     :value="item.value" :label="item.label"></el-option>
        </el-select>
      </div>

      <div :class="{'is-pack-down': presetColorList.length>36 && !isPackUp}">
        <template v-for="c in presetColorList">
          <div
              v-if="!isTransparent(c)"
              class="vc-sketch-presets-color"
              :aria-label="'Color:' + c"
              :style="{background: c}"
              @click="handlePreset(c)">
          </div>
          <div
              v-else
              :aria-label="'Color:' + c"
              class="vc-sketch-presets-color check-board"
              @click="handlePreset(c)">
            <check-board/>
          </div>
        </template>
      </div>

      <div v-if="presetColorList.length>36"
           class="vc-sketch-presets-more"
           :class="{'is-pack-up': isPackUp}"
           @click="isPackUp=!isPackUp"
      >
        <svg width="14" height="9" xmlns="http://www.w3.org/2000/svg">
          <path
              d="M13.263 3.56a.5.5 0 1 1 .474.88L6.99 8.073.748 4.432a.5.5 0 0 1 .504-.864L7.01 6.927zm0-3a.5.5 0 1 1 .474.88L6.99 5.073.748 1.432a.5.5 0 0 1 .504-.864L7.01 3.927z"
              fill="#8D9EA7" fill-rule="nonzero"></path>
        </svg>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import { computed, defineComponent, ref } from 'vue'
import tinycolor from 'tinycolor2'
import {
  _colorChange,
  isValidHex,
  PresetColors,
  RECENT_COLORS,
  refreshRecentColors,
} from './useSketch'
import '../style/index.scss'
import Saturation from './common/Saturation.vue'
import Hue from './common/Hue.vue'
import Alpha from './common/Alpha.vue'
import CheckBoard from './common/CheckBoard.vue'
import EditableInput from './common/EditableInput.vue'
import { ElSelect, ElOption } from 'element-pe'
import 'element-pe/es/components/select/style/css'

export default defineComponent({
  name: 'Sketch',
  components: { EditableInput, CheckBoard, Alpha, Hue, Saturation, ElSelect, ElOption },
  props: {
    colors: {
      type: Object,
      required: true,
    },
    presetColors: {
      type: Array,
      default() {
        return PresetColors
      },
    },
    disableAlpha: {
      type: Boolean,
      default: false,
    },
    disableFields: {
      type: Boolean,
      default: false,
    },
  },
  emits: ['update:colors', 'change-preset-group'],
  setup(props: any, { emit }) {
    const val = ref(_colorChange(props.colors))

    let oldHueCache
    const colorChange = (data: any, oldHue?: any) => {
      oldHueCache = val.value.hsl.h
      val.value = _colorChange(data, oldHue || oldHueCache)
      emit('update:colors', val.value)
    }

    const groups = ref([
      { value: 'recent-use', label: '最近使用' },
      ...props.presetColors,
    ])

    refreshRecentColors()
    const selectedGroup = ref(RECENT_COLORS.value.length > 0 ? groups.value[0].value : groups.value[1].value)
    const presetColorList = computed(() => {
      if (selectedGroup.value === 'recent-use') {
        return RECENT_COLORS.value
      } else {
        const found = props.presetColors.find((item: any) => item.value === selectedGroup.value)
        return found ? found.colors : []
      }
    })

    const isPackUp = ref(false)

    return {
      selectedGroup,
      groups,
      presetColorList,
      isPackUp,

      val,
      hex: computed(() => {
        let hex
        if (val.value.a < 1) {
          hex = val.value.hex8
        } else {
          hex = val.value.hex
        }
        return hex
      }),
      activeColor: computed(() => {
        const rgba = val.value.rgba
        return 'rgba(' + [rgba.r, rgba.g, rgba.b, rgba.a].join(',') + ')'
      }),
      isTransparent(color: string) {
        return tinycolor(color).getAlpha() === 0
      },
      handlePreset(c: string) {
        colorChange({ hex: c, source: 'hex' })
      },
      childChange(data: any) {
        colorChange(data)
      },
      inputChange(data: any) {
        if (!data) {
          return
        }
        if (data.hex) {
          if (isValidHex(data.hex)) {
            colorChange({ hex: data.hex, source: 'hex' })
          }
        } else if (data.r || data.g || data.b || data.a) {
          colorChange({
            r: data.r || val.value.rgba.r,
            g: data.g || val.value.rgba.g,
            b: data.b || val.value.rgba.b,
            a: data.a || val.value.rgba.a,
            source: 'rgba',
          })
        }
      },
      onPresetsChange(group: string) {
        emit('change-preset-group', group)
      },
    }
  },
})
</script>